/*
* JSA
*
* JSA is a light-weight framework, which consists of following parts:
* factory method providing prototypal inheritance for modules
* jsa.BaseAbstract and jsa.WidgetAbstract classes, bringing
*   YUI widget experience (http://yuilibrary.com/yui/docs/widget/) into your application
* jsa.Hooks allowing to assign factory hooks (e.g. interfaces, mixins, type hinting control)
*
* JSA can be exploited over any JS-library. You just have to specify a callback for querySelector
* function of the library you utilize.
*
* @example
* var AbstractModule = function () {
*   var privateProp = "..";
*   return {
*       __extends__: jsa.BaseAbstract
*       // module public constructor
*       init: function () {
*       },
*       publicProp: "..."
*   };
* },
* ConcreteModule = function(optionalArg) {
*   return {
*       __extends__: AbstractModule
*   };
* },
* o = ConcreteModule.makeInstance(optionalArg);
* o instanceof ConcreteModule === true
* o instanceof AbstractModule === true
* o instanceof jsa.BaseAbstract === true
*
* @package JSA
* @author sheiko
* @version 2.03
* @license MIT
* @copyright (c) Dmitry Sheiko http://www.dsheiko.com
* @jscs standard:Jquery
* Code style: http://docs.jquery.com/JQuery_Core_Style_Guidelines
*/
/*jshint sub:true*/
/*global module: false */
(function( global, undefined ) {
    "use strict";
    /** @namespace */
    global.jsa = global.jsa || {};
    /**
     * Helper
     */
    global.jsa.isArray = function ( obj ) {
        return ( Object.prototype.toString.call( obj ) === '[object Array]' );
    };
    /**
     * Factory hooks manager
     * Any hook assigned by the object will be invoked right after factory creates a new instance
     * @module
     */
    global.jsa.Hook = (function( extHooks ) {
        var hooks = extHooks;
        return {
            /**
             * Append a given hook to the list
             * @param (function) fn
             */
            push : function( fn ) {
                hooks.push( fn );
            },
            /**
             * Invoke all the assigned hooks
             * @param {object} instance
             * @param {array}  args
             */
            invokeAll: function( instance, args ) {
                var len = hooks.length, i = 0;
                for ( ; i < len; i++ ) {
                    hooks[ i ]( instance, args );
                }
            }
        };
    }( global.jsa.Hook || [] ));

    /**
     * Create instance of a given module and pass arguments to its constructor
     * @see Function.prototype.createInstance
     * @param {object} module - class object
     * @param {array} args - array of arguments
     * @return {object} instance
     */
    global.jsa.createInstance = function( module, args ) {
        var key,
            instance,
            members = module.apply( module.prototype, args || [] ) || {},
            Fn = function () {};

        if ( members.hasOwnProperty( "__extends__" ) &&
            members[ "__extends__" ] ) {
            module.prototype =
                global.jsa.createInstance( members[ "__extends__" ], args );
        }
        // Link to the supertype
        Fn.prototype = module.prototype;
        // Mix in members
        for ( key in members ) {
            if ( members.hasOwnProperty( key ) ) {
                Fn.prototype[ key ] = members[ key ];
            }
        }
        instance = new Fn();
        members.hasOwnProperty("__constructor__") &&
            members[ "__constructor__" ].apply( instance, args || [] );
        return instance;
    };
    /**
     * Factory method implementing prototypal inheritance for modules
     * Arguments of the method are being passed to the context constructor
     * @return (object) instance
     */
    Function.prototype.createInstance = function () {
        var instance = global.jsa.createInstance( this, arguments );
        global.jsa.Hook.invokeAll( instance, arguments );
        return instance;
    };

})( this );